home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / DockExtenders / LaunchPad / Source / IconView.m < prev    next >
Text File  |  1993-12-16  |  14KB  |  603 lines

  1. // IconView.m
  2.  
  3. /*
  4.  * Copyright 1991 RightBrain Software.  All rights reserved.
  5.  *
  6.  * No part of this code may be reproduced in any form, compiled
  7.  * or source code, nor used for any purpose without the express
  8.  * written permission of RightBrain Software.
  9.  * 
  10.  * Entered into the public domain 12/15/93 by RightBrain Software.
  11.  *
  12.  */
  13.  
  14. #import <strings.h>
  15. #import <dpsclient/psops.h>
  16. #import <dpsclient/wraps.h>
  17. #import <appkit/NXImage.h>
  18. #import <objc/NXStringTable.h>
  19. #import <appkit/appkit.h>
  20.  
  21. #import "CopyIcon.h"
  22. #import "Controller.h"
  23. #import "IconView.h"
  24. // #import "Defaults.h"
  25.  
  26. @implementation IconView
  27.  
  28. static NXRect    fileRect = {{2.0, 2.0}, {54.0, 54.0}};
  29.     
  30.  
  31. /* instance methods */
  32.  
  33. /****************************** initFrame */
  34. - initFrame:(NXRect *)frameRect
  35. {
  36.     NXSize    imageSize = {54.0, 54.0};
  37. //    NXSize    imageSize = {96.0, 96.0};
  38.     
  39.     [super initFrame:frameRect];
  40.  
  41.     iconImage = [[NXImage alloc] initSize:&imageSize];
  42.     stringTable = [[NXApp delegate] stringTable];
  43.     hasIcon = NO;
  44.     autoLaunch = NO;
  45.     [self clear];
  46.     
  47.     return self;
  48. }
  49.  
  50. /****************************** bounds */
  51. - (NXRect *)bounds;
  52. {
  53.     return &bounds;
  54. }
  55.  
  56.  
  57. /****************************** setAppOrFile */
  58. - setAppOrFile:(int)ilk;
  59. {
  60.     isApplication = (ilk == NX_ISAPPLICATION);
  61.     isBogus = (ilk == MISSING_FILE);
  62.     return self;
  63. }
  64.  
  65.  
  66. /****************************** acceptsFirstMouse */
  67. - (BOOL)acceptsFirstMouse
  68. {
  69.     return YES;
  70. }
  71.  
  72.  
  73. /****************************** acceptsFirstMouse */
  74. - (BOOL)hasIcon
  75. {
  76.     return hasIcon;
  77. }
  78.  
  79.  
  80. /****************************** filename */
  81. - (char *)filename;
  82. {
  83.     return filename;
  84. }
  85.  
  86.  
  87. /****************************** appname */
  88. - (char *)appname;
  89. {
  90.     return appname;
  91. }
  92.  
  93.  
  94. /****************************** dirname */
  95. - (char *)dirname;
  96. {
  97.     return dirname;
  98. }
  99.  
  100.  
  101. /****************************** tellName */
  102. - tellName:sender;
  103. {
  104.     fprintf ( stderr, "List: %s\n", filename );
  105.     [self display];
  106.     return self;
  107. }
  108.  
  109.  
  110. /****************************** setFilename */
  111. - setFilename:(const char *)name multipleSelected:(BOOL)multipleSelected
  112. {
  113.     char *lastSlash, *stringPosition, *tmpPosition;
  114.     
  115.   /*
  116.    * we need to remember this so that the we don't let the user drag the
  117.    * multple-files-selected-icon from the icon well
  118.    */
  119.     multipleFiles = multipleSelected;
  120.     
  121.   /* save the file name if necessary */
  122.     if (!multipleSelected) {
  123.     strcpy ( filename, name );
  124.     strcpy ( appname, (rindex(name, '/') + 1) );
  125.     strcpy ( dirname, name );
  126.     lastSlash = rindex(dirname, '/');
  127.     if (lastSlash) *lastSlash = '\0';
  128.     } else {
  129.     strcpy ( filename, name );
  130.     appname[0] = '\0';
  131.     strcpy ( buff, name );
  132.     tmpPosition = buff; // gcr
  133.     for ( stringPosition=buff; stringPosition!=NULL; stringPosition++ ) {
  134.         if ( *stringPosition == '\t' ) {
  135.         *stringPosition = '\0';
  136.         if ( appname[0] != '\0' ) strcat ( appname, ", " );
  137.         strcat ( appname, (rindex(tmpPosition, '/')+1) );
  138.         tmpPosition = stringPosition + 1;
  139.         } else if ( *stringPosition == '\0' ) {
  140.         if ( appname[0] != '\0' ) strcat ( appname, ", " );
  141.         strcat ( appname, (rindex(tmpPosition, '/')+1) );
  142.         break;
  143.         }
  144.     }
  145.     strcpy ( dirname, name );
  146.     stringPosition = index ( dirname, '\t' );
  147.     if ( stringPosition ) *stringPosition = '\0';
  148.     lastSlash = rindex(dirname, '/');
  149.     if (lastSlash) *lastSlash = '\0';
  150.     }
  151.     if ( dirname == NULL || strlen(dirname) < 2 ) {
  152.     strcpy ( dirname, "root directory" );
  153.     }
  154.     
  155.     return self;
  156. }
  157.  
  158.  
  159. /****************************** setMyCheckBox */
  160. - setMyCheckBox:theBox;
  161. {
  162.     myCheckBox = theBox;
  163.     return self;
  164. }
  165.  
  166.  
  167. /****************************** myCheckBox */
  168. - myCheckBox;
  169. {
  170.     return myCheckBox;
  171. }
  172.  
  173.  
  174. /****************************** setMyWideBox */
  175. - setMyWideBox:theBox;
  176. {
  177.     myWideBox = theBox;
  178.     return self;
  179. }
  180.  
  181.  
  182. /****************************** myWideBox */
  183. - myWideBox;
  184. {
  185.     return myWideBox;
  186. }
  187.  
  188.  
  189. /****************************** setMyLabelText */
  190. - setMyLabelText:theText;
  191. {
  192.     myLabelText = theText;
  193.     return self;
  194. }
  195.  
  196.  
  197. /****************************** myLabelText */
  198. - myLabelText;
  199. {
  200.     return myLabelText;
  201. }
  202.  
  203.  
  204. /****************************** setMyDirText */
  205. - setMyDirText:theText;
  206. {
  207.     myDirText = theText;
  208.     return self;
  209. }
  210.  
  211.  
  212. /****************************** myDirText */
  213. - myDirText;
  214. {
  215.     return myDirText;
  216. }
  217.  
  218.  
  219. /****************************** toggleCheckBox */
  220. - toggleCheckBox:sender;
  221. {
  222.     if ( autoLaunch ) {
  223.     autoLaunch = FALSE;
  224.     } else {
  225.     autoLaunch = TRUE;
  226.     }
  227.     if ( sender != [window delegate] ) {
  228.     [[window delegate] writeFileList:
  229.         [[window delegate] listFileName]
  230.     ];
  231.     }
  232.     return self;
  233. }
  234.  
  235.  
  236. /****************************** autoLaunch */
  237. - (int)autoLaunch;
  238. {
  239.     return autoLaunch;
  240. }
  241.  
  242.  
  243. /****************************** takeIconFromWindow */
  244. - takeIconFromWindow:(int)windowNumber :(float)x :(float)y :(float)width
  245.   :(float)height
  246. {
  247.   /* copy the icon into our nximage */
  248.     if ( windowNumber == 0 ) return NULL;
  249.     [iconImage lockFocus];
  250.     copyIconPicture(windowNumber, x, y, width, height);        // was + 2.0
  251.     [iconImage unlockFocus];
  252.     
  253.   /* now display the new image */
  254.     showFile = YES;
  255.     hasIcon = YES;
  256.     [self display];
  257.     
  258.     return self;
  259. }
  260.  
  261.  
  262.  
  263. /****************************** takeIconFromData */
  264. - takeIconFromData : (char *)data : (int)length;
  265. {
  266.     float width, height, bits;
  267.     
  268.   /* copy the icon into our nximage */
  269.     if ( length == 0 || !data ) return NULL;
  270.     width = height = 48.0;
  271.     bits = length / (width * height / 8);
  272.     [iconImage lockFocus];
  273.     imageIconPicture ( (int)width, (int)height, (int)bits, data );
  274.     [iconImage unlockFocus];
  275.     
  276.   /* now display the new image */
  277.     showFile = YES;
  278.     hasIcon = YES;
  279.     [self display];
  280.     
  281.     return self;
  282. }
  283.  
  284.  
  285.  
  286. /****************************** takeIconFromTIFF */
  287. - takeIconFromTIFF : (char *)fname;
  288. {
  289.     id tmp;
  290.     tmp = iconImage;
  291.     iconImage = [[NXImage alloc] initFromFile:fname];
  292.     if ( iconImage ) {
  293.     if ( tmp ) [tmp free];
  294.     }
  295.     showFile = YES;
  296.     hasIcon = YES;
  297.     [self display];
  298.     
  299.     return self;
  300. }
  301.  
  302.  
  303.  
  304. /****************************** clear */
  305. - clear
  306. {
  307.   /* remove any image from the nximage */
  308.     [self display];
  309.     return self;
  310.     
  311.     [iconImage lockFocus];
  312.     PSsetgray(NX_LTGRAY);
  313.     NXRectFill(&bounds);
  314.     [iconImage unlockFocus];
  315.     
  316.   /* now display the blank nximage */
  317.     [self lockFocus];
  318.     NXDrawGrayBezel(&bounds, NULL);
  319.     PSsetgray(NX_LTGRAY);
  320.     NXRectFill(&bounds);
  321.     [self unlockFocus];
  322.  
  323.     hasIcon = NO;
  324.  
  325.     return self;
  326. }
  327.  
  328.  
  329. /****************************** openSelf */
  330. - openSelf:sender;
  331. {
  332.     id speaker;
  333.     int flag, response, files;
  334.     char *extension, *program, *newPath, *stringPosition;
  335.     char *tmpFile;
  336.     char launch[24];
  337.  
  338.     speaker = [NXApp appSpeaker];
  339.     [speaker setSendPort:NXPortFromName(NX_WORKSPACEREQUEST, NULL)];
  340.  
  341.     // the number of tabs + 1 equals the number of files dragged in
  342.     stringPosition = filename;
  343.     files = 1; // gcr
  344.     while (stringPosition = index(stringPosition, '\t')) {
  345.       files++;
  346.       stringPosition++;
  347.     }
  348.     strcpy ( buff, filename );
  349.     while ( files ) {
  350.         if ( files >= 1 ) {
  351.         stringPosition = rindex ( buff, '\t' );
  352.         if ( stringPosition ) {
  353.         tmpFile = stringPosition + 1;
  354.         *stringPosition = '\0';
  355.         } else {
  356.         tmpFile = buff;
  357.         }
  358.     } else {
  359.         tmpFile = buff;
  360.     }
  361.     files--;
  362.     // check our instance variable (set from Controller's getFileInfo)
  363.     if ( isApplication ) {
  364.         extension = rindex ( tmpFile, '.' );
  365.         if ( extension && !strcmp(extension,".app") ) {
  366.         program = rindex ( tmpFile, '/' );
  367.         newPath = (char *)malloc(strlen(tmpFile) + strlen(program));
  368.         sprintf ( newPath, "%s%s", tmpFile, program );
  369.         newPath [ strlen(newPath) - 4 ] = '\0';
  370.         [NXApp deactivateSelf];
  371.         [speaker launchProgram:newPath ok: &flag];
  372.         free ( newPath );
  373.         } else {
  374.         [NXApp deactivateSelf];
  375.         [speaker launchProgram:tmpFile ok: &flag];
  376.         }
  377.         strcpy ( launch, "launch" );
  378.     } else {
  379.         [NXApp deactivateSelf];
  380.         [speaker openFile:tmpFile ok: &flag];
  381.         strcpy ( launch, "open" );
  382.     }
  383.     if ( !flag ) {
  384.         response = NXRunAlertPanel ( "Launch",
  385.         "Could not %s %s", "Remove It", "OK", NULL, launch, tmpFile
  386.         );
  387.         response = NXRunAlertPanel (
  388.         [stringTable valueForStringKey:"launch"],
  389.         [stringTable valueForStringKey:"launchCANT"],
  390.         [stringTable valueForStringKey:"launchRemove"],
  391.         [stringTable valueForStringKey:"OK"],
  392.         NULL,
  393.         [stringTable valueForStringKey:launch],
  394.         filename
  395.         );
  396.         if ( response == NX_ALERTDEFAULT ) {
  397.         [[NXApp delegate] removeFileFromScroller:filename];
  398.         return self;
  399.         }
  400.     } else {
  401.         [NXApp deactivateSelf];
  402.     }
  403.     }
  404.     return self;
  405. }
  406.  
  407.  
  408. /****************************** openSelfIfAutoLaunch */
  409. - openSelfIfAutoLaunch:sender;
  410. {
  411. //    id speaker;
  412. //    char *appName, *extension, *newPath;
  413.  
  414.     if ( !autoLaunch ) return self;
  415.  
  416.     [self openSelf:sender];
  417.  
  418.     // if we're autolaunching, then "hide" the app if possible
  419.     return self;
  420. }
  421.  
  422.  
  423. /****************************** highlightSelf */
  424. - highlightSelf:sender;
  425. {
  426.     [self lockFocus];
  427.     NXHighlightRect ( &bounds );
  428.     [self unlockFocus];
  429.     return self;
  430. }
  431.  
  432.  
  433. /****************************** mouseDown */
  434. - mouseDown:(NXEvent *)theEvent
  435. {
  436.     NXPoint mouseLoc;
  437.     NXPoint origLoc, newLoc;
  438.     id prevSelected;
  439.     int Yoff;
  440.     int oldMask;
  441.     int tryDrag;
  442.     NXEvent peekEvent, *nextEvent;
  443.  
  444.     if ( !filename || !(strlen(filename)) ) { NXBeep(); return self; }
  445.  
  446.     mouseLoc = theEvent->location;
  447.     origLoc = mouseLoc;
  448.     [self convertPoint: &mouseLoc fromView:[scrollR docView]];
  449.     Yoff = (int)mouseLoc.y % 54;
  450.     mouseLoc.y -= Yoff;
  451.     mouseLoc.x = 24.0;
  452.     mouseLoc.y += 24.0;
  453.     [self convertPoint: &mouseLoc toView:[scrollR docView]];
  454.     theEvent->location = mouseLoc;
  455.     
  456.     oldMask = [
  457.     window addToEventMask: NX_MOUSEDRAGGEDMASK
  458.     ];
  459.     if ( theEvent->data.mouse.click == 1  ) {
  460.     prevSelected = [[NXApp delegate] selected];
  461.     if ( prevSelected && (prevSelected != self) ) {
  462.         [prevSelected lockFocus];
  463.         [prevSelected highlightSelf:self];
  464.         [prevSelected unlockFocus];
  465.         [[NXApp delegate] setSelected:self];
  466.         [self lockFocus];
  467.         NXHighlightRect ( &bounds );
  468.         [self unlockFocus];
  469.         PSflushgraphics();  NXPing();
  470.     } else if ( !prevSelected ) {
  471.         [[NXApp delegate] setSelected:self];
  472.         [self lockFocus];
  473.         NXHighlightRect ( &bounds );
  474.         [self unlockFocus];
  475.         PSflushgraphics();  NXPing();
  476.     }
  477.     } else
  478.     if ( theEvent->data.mouse.click >= 2 ) {
  479.     [self openSelf:self];
  480.     if ( theEvent->flags & NX_ALTERNATEMASK ) {
  481.         [NXApp deactivateSelf];
  482.         [NXApp hide:self];
  483.     }
  484.     if ( theEvent->data.mouse.click >= 3 ) {
  485.         [NXApp deactivateSelf];
  486.         [NXApp hide:self];
  487.     }
  488.     return self;
  489.     } else {
  490.     // do nothing for now
  491.     }
  492.  
  493.     nextEvent = [ NXApp
  494.     peekNextEvent: NX_ALLEVENTS
  495.     into: &peekEvent
  496.     waitFor: 0.5
  497.     threshold: NX_MODALRESPTHRESHOLD
  498.     ];
  499.     if ( nextEvent != NULL ) {
  500.     tryDrag = NO;
  501.     if ( nextEvent->type == NX_LMOUSEDRAGGED ) {
  502.         [[NXApp delegate] setFrom:self];
  503.         [[window contentView] lockFocus];
  504.         PSsetinstance ( TRUE );
  505.         while ( nextEvent->type != NX_LMOUSEUP ) {
  506.         switch ( nextEvent->type ) {
  507.             case NX_MOUSEDRAGGED: {
  508.             PSnewinstance();
  509.             newLoc = nextEvent->location;
  510.             [self convertPoint: &newLoc fromView: self];
  511.             newLoc.x =  24.0;
  512.             newLoc.y = newLoc.y - 24.0;
  513.             [iconImage composite:NX_COPY toPoint:&newLoc];
  514.             PSflushgraphics();
  515.             NXPing();
  516.             } break;
  517.             default: {
  518.             } break;
  519.         }
  520.         nextEvent = [ NXApp getNextEvent: NX_ALLEVENTS ];
  521.         }
  522.         PSnewinstance();
  523.         PSsetinstance ( FALSE );
  524.         [[window contentView] unlockFocus];
  525.  
  526.         // compensate for the bottom of the window:
  527.         newLoc.y += 10.0;
  528.  
  529.         // [self convertPoint: &newLoc toView: self];
  530.  
  531.         // slide the icon to the new location
  532.         [[NXApp delegate] slideIconInScroller: self toLocation:newLoc.y];
  533.     /***
  534.         [self dragFile:filename
  535.         fromRect:&fileRect
  536.         slideBack:NO
  537.         event:theEvent
  538.         ];
  539.      ***/
  540.     } else if ( nextEvent->type == NX_LMOUSEUP ) {
  541.         // throw away mouseUp event
  542.         // nextEvent = [ NXApp getNextEvent: NX_LMOUSEUPMASK ];
  543.         nextEvent = [ NXApp getNextEvent: NX_ALLEVENTS ];
  544.         if ( nextEvent->type != NX_LMOUSEUP ) {
  545.         NXRunAlertPanel ( "Yikes",
  546.             "NextEvent was %d instead of MOUSEUPMASK",
  547.             NULL, NULL, NULL, nextEvent->type
  548.         );
  549.         }
  550.         nextEvent = [ NXApp
  551.         peekNextEvent: NX_ALLEVENTS
  552.         into: &peekEvent
  553.         waitFor: 0.25
  554.         threshold: NX_MODALRESPTHRESHOLD
  555.         ];
  556.         if ( nextEvent != NULL && nextEvent->type == NX_LMOUSEDOWN ) {
  557.         nextEvent = [ NXApp getNextEvent: NX_LMOUSEDOWNMASK ];
  558.         [self mouseDown:nextEvent];
  559.         return self;
  560.         } else {
  561.         if ( [[NXApp delegate] selected] ) {
  562.             [[[NXApp delegate] selected] highlightSelf:self];
  563.         }
  564.         [[NXApp delegate] setSelected:self];
  565.         [self lockFocus];
  566.         NXHighlightRect ( &bounds );
  567.         [self unlockFocus];
  568.         PSflushgraphics();  NXPing();
  569.         }
  570.     } else {
  571.         fprintf ( stderr, "unknown type: %d\n", nextEvent->type );
  572.     }
  573.     } else {
  574.     [[NXApp delegate] setFrom:self];
  575.     [self dragFile:filename
  576.         fromRect:&fileRect
  577.         slideBack:NO
  578.         event:theEvent
  579.     ];
  580.     }
  581.     return self;
  582. }
  583.  
  584.  
  585. /****************************** drawSelf */
  586. - drawSelf:(NXRect *)rects :(int)rectCount
  587. {
  588.     
  589.     if ( !filename || !(strlen(filename)) ) return self;
  590.     NXDrawGrayBezel(&bounds, NULL);
  591.     PSgsave();
  592.     PStranslate ( deltaX, deltaY );
  593.     [iconImage composite:NX_SOVER toPoint:&fileRect.origin];
  594.     PSgrestore();
  595.     
  596.     if ( [[NXApp delegate] selected] == self ) {
  597.     NXHighlightRect ( &bounds );
  598.     }
  599.     return self;
  600. }
  601.  
  602.  
  603. @end